﻿using EnterpriseWebsiteApi.ActionResults;
using EnterpriseWebsiteBLL;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using EnterpriseWebsiteApi.Model;
using Microsoft.Extensions.Primitives;

namespace EnterpriseWebsiteApi.ActionFilters
{
    public class JwtAuthorizeFilter : IActionFilter
    {
        private readonly IConfiguration _configuration;
        private readonly UserService _userService;
        public JwtAuthorizeFilter(IConfiguration configuration, UserService userService)
        {
            _configuration = configuration;
            _userService = userService;
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
            StringValues tokenValues;
            context.HttpContext.Request.Headers.TryGetValue("Authorization", out tokenValues);
            string token = tokenValues.ToString();

            if (string.IsNullOrEmpty(token))
            {
                context.Result = new Unauthorized("身份验证失败");
                return;
            }

            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.UTF8.GetBytes(_configuration["Jwt:Secret"]);
            var validationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(key),
                ValidateIssuer = false,
                ValidateAudience = false,
                ClockSkew = TimeSpan.Zero
            };

            try
            {
                var principal = tokenHandler.ValidateToken(token, validationParameters, out var validatedToken);
                var jwtToken = (JwtSecurityToken)validatedToken;
                if (jwtToken == null || !jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
                {
                    context.Result = new Unauthorized("JWT验证不通过");
                    return;
                }
                // 获取用户信息
                var userJson = principal.Claims.FirstOrDefault(c => c.Type == "user")?.Value;
                if (string.IsNullOrEmpty(userJson))
                {
                    context.Result = new Unauthorized("获取用户信息失败");
                    return;
                }
                else
                {
                    //验证用的id与token是否匹配
                    var user = JsonConvert.DeserializeObject<User>(userJson);
                    var userEntity = _userService.GetUserByIdAndToken(user.Id, user.Token);
                    if (userEntity == null)
                    {
                        context.Result = new Unauthorized("token验证失败" + userJson);
                        return;
                    }
                    if (userEntity.ExpDate == null)
                    {
                        context.Result = new Unauthorized();
                        return;
                    }
                    //判断当前token是否过期
                    if (DateTime.Now > userEntity.ExpDate)
                    {
                        context.Result = new Unauthorized();
                        return;
                    }
                    //把UserEntity缓存入上下文
                    context.HttpContext.Items["operator"] = userEntity;
                }
            }
            catch (SecurityTokenException ex)
            {
                context.Result = new Unauthorized();
                return;
            }
        }
    }
}
